
package com.hlkj.pay.app.merchant.ext.impl.gtzfpay.handler;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantAccessContext;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantBusinessContext;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.constant.GtzfPayConstant;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.dto.GtzfPayConfig;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.dto.req.GtzfAccessRequest;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.dto.req.GtzfApplyQueryRequest;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.dto.req.GtzfInfoQueryRequest;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.dto.req.GtzfUploadRequest;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.dto.rsp.GtzfResponse;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.dto.rsp.UploadBody;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.utils.GtzfPayRsaUtil;
import com.hlkj.pay.app.merchant.ext.impl.gtzfpay.utils.HttpUtils;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.dto.merchant.MerchantAccessDto;
import com.hlkj.pay.dto.merchant.MerchantWechatConfigDto;
import com.hlkj.pay.dto.merchant.ProviderChannelFeeConfigList;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.infrastructure.model.merchant.*;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.StringPool;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 汇付 商户进件参数处理
 * 
 * @author HlpayTeam
 * @date 2024/09/26 12:02
 */
@Slf4j
public class GtzfPayMerchantParamsHandle extends GtzfPayMerchantCommonParamsHandle {

    /**
     * 企业商户进件-新增参数组装
     *
     * @param channelMerchantAccessContext
     * @return
     */
    public static CommonResult<GtzfAccessRequest> merchantApplyParams(ChannelMerchantAccessContext channelMerchantAccessContext, GtzfPayConfig gtzfPayConfig) throws IOException {
        MerchantAccessDto merchantAccessDto = channelMerchantAccessContext.getMerchantAccessDto();
        MerchantAccessInfoDO merchantAccessInfo = merchantAccessDto.getMerchantAccessInfo();
        MerchantAccessBusinessDO merchantAccessBusiness = merchantAccessDto.getMerchantAccessBusiness();
        MerchantAccessLicenseDO merchantAccessLicenseDO = merchantAccessDto.getMerchantAccessLicense();
        MerchantAccessCardDO merchantAccessCardDO = merchantAccessDto.getMerchantAccessCard();
        List<MerchantAccessCertInfoDO> merchantAccessBenefitList = merchantAccessDto.getMerchantAccessBenefitList();
        MerchantAccessCertInfoDO merchantAccessLegal = merchantAccessDto.getMerchantAccessLegal();

        GtzfAccessRequest request = new GtzfAccessRequest();
        request.setAgetId(gtzfPayConfig.getAgetId());
        if (!StringUtils.hasText(merchantAccessInfo.getSubMchId())) {
            request.setOperType("1");
        } else {
            request.setOperType("2");
            request.setCustId(merchantAccessInfo.getSubMchId());
        }

        request.setCustLogin(merchantAccessLegal.getPhone());
        String busType = getMchtMode(merchantAccessInfo.getType(), merchantAccessLicenseDO);
        //小微
        if ("4".equals(busType)) {
            request.setBusName(merchantAccessInfo.getShortName());
            request.setManageType(merchantAccessBusiness.getSceneType() == 1 ? "03" : "01");
        } else {
            request.setBusName(merchantAccessLicenseDO.getName());
            request.setRefName(merchantAccessInfo.getShortName());
            request.setLicenseno(merchantAccessLicenseDO.getLicenseCode());
            request.setBusStartDate(DateUtils.yyyyMMddDelDash(merchantAccessLicenseDO.getLicenseBeginDate()));
            if(merchantAccessLicenseDO.getLicenseValidityType() == 1) {
                request.setBusEndDate("长期");
            } else {
                request.setBusEndDate(merchantAccessLicenseDO.getLicenseEndDate());
            }
            request.setBusType(busType);
            request.setCretType(licenseType(merchantAccessLicenseDO.getLicenseType()));
            request.setNolegalCertType(getOldCerType(merchantAccessLegal.getCertType()));

            request.setAccountType(getAccType(merchantAccessCardDO.getType()));
            if ("03".equals(request.getAccountType())) {
                request.setStlName(merchantAccessCardDO.getName());
                request.setAccCredType(getOldCerType(merchantAccessCardDO.getCertType()));
                request.setAccCredNo(merchantAccessCardDO.getCertNo());
                request.setAccCredStartDate(DateUtils.yyyyMMddDelDash(merchantAccessCardDO.getCertBeginDate()));
                if (merchantAccessCardDO.getCertValidityType() == 1) {
                    request.setAccCredEndDate("长期");
                } else
                    request.setAccCredEndDate(DateUtils.yyyyMMddDelDash(merchantAccessCardDO.getCertEndDate()));
            }
        }
        request.setMcccode(merchantAccessBusiness.getMcc());
        request.setProvId(merchantAccessBusiness.getProvinceCode());
        request.setCityId(merchantAccessBusiness.getCityCode());
        request.setAreaId(merchantAccessBusiness.getAreaCode());
        request.setCustAddr(merchantAccessBusiness.getAddress());
        request.setCustName(merchantAccessLegal.getName());
        request.setCredNo(merchantAccessLegal.getCertNo());
        request.setCredStartDate(DateUtils.yyyyMMddDelDash(merchantAccessLegal.getCertBeginDate()));
        if (merchantAccessLegal.getCertValidityType() == 1) {
            request.setCredEndDate("长期");
        } else
            request.setCredEndDate(DateUtils.yyyyMMddDelDash(merchantAccessLegal.getCertEndDate()));
        request.setMobileNo(merchantAccessLegal.getPhone());
        request.setAccountName(merchantAccessCardDO.getName());
        request.setAccountNo(merchantAccessCardDO.getCardNo());
        request.setBankCode(merchantAccessCardDO.getBankCode());
        request.setBranchname(merchantAccessCardDO.getBankName());
        request.setBankno(merchantAccessCardDO.getBranchCode());

        request.setCustChanType("0");
        request.setRefPower("1");

        request.setTimestamp("");
        if ("2".equals(request.getBusType())) {
            MerchantAccessCertInfoDO merchantAccessCertInfoDO = merchantAccessDto.getMerchantAccessLegal();
            if (merchantAccessBenefitList != null && merchantAccessBenefitList.size() > 1) {
                merchantAccessCertInfoDO = merchantAccessBenefitList.get(0);
            }
            request.setBeneficiarName(merchantAccessCertInfoDO.getName());
            request.setBeneficiarStaff("经理");
            request.setBeneficiarPercent("100");
            request.setBeneficiarCredNo(merchantAccessCertInfoDO.getCertNo());
            request.setBeneficiarCertType(getOldCerType(merchantAccessLegal.getCertType()));
            request.setBeneficiarAddr(merchantAccessCertInfoDO.getAddress());
            request.setBeneficiarStartTime(DateUtils.yyyyMMddDelDash(merchantAccessCertInfoDO.getCertBeginDate()));

            if (merchantAccessCertInfoDO.getCertValidityType() == 1) {
                request.setBeneficiarEndTime("长期");
            } else
                request.setBeneficiarEndTime(DateUtils.yyyyMMddDelDash(merchantAccessCertInfoDO.getCertEndDate()));
        }
        request.setVersion("1.0.0");
        getSceneFunctionList(channelMerchantAccessContext.getMerchantFeeConfigList(), request);

        CommonResult<String> uploadRes = addProcessFileId(channelMerchantAccessContext, gtzfPayConfig, busType, request.getAccountType());
        if (!uploadRes.isSuccess()) {
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_FILE_ERROR.getCode(), uploadRes.getMsg());
        }
        request.setTimestamp(uploadRes.getData());
        return CommonResult.success(request);
    }

    /**商户进件状态查询*/
    public static CommonResult<GtzfApplyQueryRequest> queryApplyStatus(String subMchid, GtzfPayConfig gtzfPayConfig) {
        GtzfApplyQueryRequest bodyMap = new GtzfApplyQueryRequest();
        bodyMap.setAgetId(gtzfPayConfig.getAgetId());
        bodyMap.setAuthType("0");
        bodyMap.setVersion("1.0.0");
        bodyMap.setCustId(subMchid);
        return CommonResult.success(bodyMap);
    }

    /**商户详情信息查询*/
    public static CommonResult<GtzfInfoQueryRequest> queryMerchant(String custLogin, String subMchid, GtzfPayConfig gtzfPayConfig) {
        GtzfInfoQueryRequest bodyMap = new GtzfInfoQueryRequest();
        bodyMap.setAgetId(gtzfPayConfig.getAgetId());
        bodyMap.setCustLogin(custLogin);
        bodyMap.setVersion("1.0.0");
        bodyMap.setCustId(subMchid);
        return CommonResult.success(bodyMap);
    }

    /**根据联行号获取银行缩写*/
    public static CommonResult<Map<String, String>> queryInfoByCard(String bankNo, GtzfPayConfig gtzfPayConfig) {
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("lineNum", bankNo);
        bodyMap.put("version", "1.0.0");
        return CommonResult.success(bodyMap);
    }

    /**H5安心签*/
    public static CommonResult<Map<String, String>> getSignH5Url(String custId, GtzfPayConfig gtzfPayConfig) {
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("version", "1.0.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**安心签发短信验证码*/
    public static CommonResult<Map<String, String>> sendAxqCode(String custId, String custLogin, String identNo, GtzfPayConfig gtzfPayConfig) {
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("custLogin", custLogin);
        bodyMap.put("phone", custLogin);
        bodyMap.put("identNo", identNo);
        bodyMap.put("isSendVoice", "0");
        bodyMap.put("version", "1.0.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**安心签补签*/
    public static CommonResult<Map<String, String>> supplementary(String checkCode, String custId, GtzfPayConfig gtzfPayConfig) {
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("checkCode", checkCode);
        bodyMap.put("version", "1.0.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**安心签合同预览*/
    public static CommonResult<Map<String, String>> previewContract(String custLogin, GtzfPayConfig gtzfPayConfig) {
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custLogin", custLogin);
        bodyMap.put("conType", "1");
        bodyMap.put("version", "1.0.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**微信/支付宝商户服务化配置信息配置*/
    public static CommonResult<Map<String, String>> authConfig(String custId, GtzfPayConfig gtzfPayConfig) {
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("version", "1.0.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**查询微信/支付宝报备信息*/
    public static CommonResult<Map<String, String>> getReportInfo(GtzfPayConfig gtzfPayConfig, String mchSubid) {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", mchSubid);
        bodyMap.put("payWay", "00");
        bodyMap.put("version", "1.0.0");
        return CommonResult.success(bodyMap);
    }

    /**微信配置/yyfsevr/addCust/appidConfig*/
    public static CommonResult<Map<String, String>> wxConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext, GtzfPayConfig gtzfPayConfig, MerchantAccessAuthDO merchantAccessAuth) {
        MerchantWechatConfigDto merchantWechatConfigDto = channelMerchantBusinessContext.getMerchantWechatConfigDto();
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", merchantAccessInfo.getSubMchId());
        bodyMap.put("wxSubMercid", merchantAccessAuth.getSubMchId());

        if (StringUtils.hasText(merchantWechatConfigDto.getJsAPIPath())) {
            bodyMap.put("authPath", merchantWechatConfigDto.getJsAPIPath());
        } else {
            bodyMap.put("appid", merchantWechatConfigDto.getAppId());
            bodyMap.put("payType", "01");
            bodyMap.put("payWay", "01");
        }
        bodyMap.put("agetAppid", gtzfPayConfig.getAgetAppid());
        bodyMap.put("version", "1.0.0");
        return CommonResult.success(bodyMap);
    }

    /**微信/支付宝报备*/
    public static CommonResult<Map<String, String>> authApply(GtzfPayConfig gtzfPayConfig, String custId) {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("version", "1.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**微信配置查询*/
    public static CommonResult<Map<String, String>> wxConfigQuery(GtzfPayConfig gtzfPayConfig, String custId, MerchantAccessAuthDO merchantAccessAuth) {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("wxSubMercid", merchantAccessAuth.getSubMchId());
        bodyMap.put("version", "1.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**支付宝认证授权查询/yyfsevr/auth/zfbApplyResult*/
    public static CommonResult<Map<String, String>> aliAuthQuery(GtzfPayConfig gtzfPayConfig, String custId) {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("version", "1.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**微信认证授权查询/yyfsevr/auth/wxApplyResult*/
    public static CommonResult<Map<String, String>> wxAuthQuery(GtzfPayConfig gtzfPayConfig, String custId) {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("version", "1.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    /**微信获取商户授权状态*/
    public static CommonResult<Map<String, String>> wxAuthState(GtzfPayConfig gtzfPayConfig, String custId, String thirdMercId) {
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("agetId", gtzfPayConfig.getAgetId());
        bodyMap.put("custId", custId);
        bodyMap.put("version", "1.0");
        bodyMap.put("timeStamp", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        return CommonResult.success(bodyMap);
    }

    private static void getSceneFunctionList(List<ProviderChannelFeeConfigList> merchantFeeConfigList, GtzfAccessRequest request) {
        request.setRateWx("0.3");
        request.setRateWx("0.3");
        request.setRateYlCap0("0.6");
        request.setRateYlCap1("0.6");
        request.setRateYlRat0("0.6");
        request.setRateYlRat1("0.6");
        request.setRatePosJy("0.6");
        request.setRatePosJb("0.6");
        request.setRatePosDy("0.55");
        request.setRatePosDb("0.6");
        request.setMoneyPosJy("2000");
        request.setMoneyPosJb("2500");
        request.setRatePosM("0.6");
        request.setRatePosS("0.6");
        Map<Integer, List<ProviderChannelFeeConfigList>> merchantFeeConfigMap = merchantFeeConfigList.stream()
                .collect(Collectors.groupingBy(merchantFeeConfig -> (merchantFeeConfig.getPayWayDO().getType())));
        merchantFeeConfigMap.forEach((index, value) -> {
            value.forEach(feeConfig -> {
                PayWayDO payWayDO = feeConfig.getPayWayDO();
                    switch (PayEnums.PAY_TYPE.fromByCode(payWayDO.getType())) {
                        case WECHAT:
                            request.setRateWx(feeConfig.getDefaultFeeConfigValue().getRateBase().toString());
                            break;
                        case ALIPAY:
                            request.setRateZfb(feeConfig.getDefaultFeeConfigValue().getRateBase().toString());
                            break;
                        case UNION_APY:
                            request.setRateYlCap0(feeConfig.getDefaultFeeConfigValue().getRateBase().toString());
                            request.setRateYlCap1(feeConfig.getDefaultFeeConfigValue().getRateBase().toString());
                            break;
                        case FUNCTION:
                            //优先D1为准
                            if (!StringUtils.hasText(request.getStlType()) || !"2".equals(request.getStlType())) {
                                if (MerchantEnum.SETTLE_CYCLE.T1.getPayWayCode().equals(payWayDO.getCode())) {
                                    request.setStlType("1");
                                    request.setRateTx("");
                                } else {
                                    request.setStlType("2");
                                    request.setRateTx(feeConfig.getDefaultFeeConfigValue().getRateBase().toString());
                                }
                            }
                            break;
                    }
//                }
            });
        });
        if (!StringUtils.hasText(request.getStlType())) {
            request.setStlType("2");
        }
    }

    //01 对公 02法人对私 03非法人对私 。示例：02
    private static String getAccType(Integer typeId) {
        if (typeId == 0) {
            return "01";
        } else if (typeId == 1) {
            return "02";
        } else {
            return "03";
        }
    }

    private static String getOldCerType(String type) {
//        1:身份证
//        2:护照
//        3:军官证
//        4:士兵证
//        5:回乡证
//        6:户口本
//        7:外国护照
//        8:其他
//        9:暂住证
//        10:警官证
//        11:文职干部证
//        12:港澳台同胞通行证
//        13:外国人居留证
//        14:台胞证
//        15:港澳台居住证

//        0:身份证，1:护照，2:港澳居民往来内地通行证（回乡证），3:台湾居民往来内地通行证（台胞证），4:外国人永久居留证，5港澳居民居住证，6:台湾居民居住证，7:执行事务合伙人
        switch (type) {
            case "1":
                return "0";
            case "2":
                return "1";
            case "5":
                return "2";
            case "15":
                return "5";
            case "12":
                return "3";
            case "13":
                return "6";
        }
        return "";
    }

    public static String licenseType(String code) {
        // 营业执照类型：
        // 1：营业执照
        // 2：营业执照(多证合一)
        // 3：事业单位法人证书
        // 4：社会团体法人登记证书
        // 5：民办非企业单位登记证书
        // 6：基金会法人登记证书
        // 7：宗教活动场所登记证
        // 8：其他证书/批文/证明
        // 9：执业许可证/执业证
        // 10：基层群众性自治组织特别法人统一社会信用代码证
        // 11：农村集体经济组织登记证
        // 12：业主委员会备案证明

        //默认：
        // 1.事业单位法人证书 2.统一社会信用代码证书 3.有偿服务许可证（军队医院适用） 4.医疗机构执业许可证（军队医院适用） 5.企业营业执照（挂靠企业的党组织适用） 6.机构组织代码证（政府机关适用）
        // 7.其他证书/批文/证明 8.社会团体法人登记证书 9.民办非企业单位登记证书 10.基金会法人登记证书 11.慈善组织公开募捐资格证书
        // 12.农民专业合作社法人营业执照 13.宗教活动场所登记证书，14基层群众性自治组织特别法人统一信用代码证、15执业许可证/执业证（含律师事务所职业许可证、基层法律服务所执业证、司法鉴定许可证）、16农村集体经济组织登记证
        switch (code) {
            case "1":
            case "2":
                return "2";
            case "3":
                return "1";
            case "4":
                return "8";
            case "5":
                return "9";
            case "6":
                return "10";
            case "7":
                return "13";
            case "9":
                return "15";
            case "10":
                return "14";
            case "11":
                return "16";
            default:
                return "7";
        }
    }

    //商户经营类型（1个体工商户 2企业 3政府及事业单位 4小微 5其他机构组织）
    private static String getMchtMode(Integer merchantType, MerchantAccessLicenseDO merchantAccessLicenseDO) {
        if (merchantType == 1) {
            return "4";
        } else {
            switch (merchantAccessLicenseDO.getCompanyType()) {
                case "1":
                case "7":
                    return "3";
                case "5":
                    return "1";
                case "2":
                case "3":
                case "4":
                    return "2";
            }
            return "5";
        }
    }

    /**
     * 进件返回参数解析
     *
     * @param resMap
     * @param channelMerchantAccessContext
     */
    public static void merchantApplyParamsParse(JSONObject resMap, ChannelMerchantAccessContext channelMerchantAccessContext, GtzfAccessRequest params) {
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessInfo();
        String retCode = resMap.getStr("code");
        String retMsg = resMap.getStr("msg");
        if ("000000".equals(retCode)) {
            merchantAccessInfo.setApplyNo(params.getTimestamp());
            JSONObject dataObj = resMap.getJSONObject("data");
            merchantAccessInfo.setSubMchId(dataObj.getStr("custId"));
            channelMerchantAccessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.SUBMIT);
            channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.CHANNEL_APPROVE);
        } else {
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
            if (StringUtils.hasText(retMsg)) {
                channelMerchantAccessContext.setRemark(retMsg);
            } else {
                channelMerchantAccessContext.setRemark("国通支付进件返回错误信息为空,错误码为:" + retCode);
            }
        }
    }

    /**
     * 新增文件参数转换
     *
     * @param channelMerchantAccessContext
     */
    public static CommonResult<String> addProcessFileId(ChannelMerchantAccessContext channelMerchantAccessContext, GtzfPayConfig gtzfPayConfig, String mchtMode, String acctType) {
        MerchantAccessLicenseDO merchantAccessLicense = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessLicense();
        MerchantAccessCertInfoDO merchantAccessCert = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessLegal();
        MerchantAccessCardDO merchantAccessCard = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessCard();
        MerchantAccessBusinessDO merchantAccessBusinessDO = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessBusiness();
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessInfo();
        boolean test = channelMerchantAccessContext.isTest();

        try {
            // 法人身份证人像面
            CommonResult<String> res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(),"", "1", merchantAccessCert.getCertFrontUrl(), merchantAccessInfo.getSubMchId(), test);
            if (!res.isSuccess()) {
                throw new Exception(res.getMsg());
            }
            String timestamp = res.getData();
            // 法人身份证国徽面
            res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "2", merchantAccessCert.getCertBackUrl(), merchantAccessInfo.getSubMchId(), test);
            if (!res.isSuccess()) {
                throw new Exception(res.getMsg());
            }

            // 营业场所门头照
            res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "4", merchantAccessBusinessDO.getStoreHeaderUrl(), merchantAccessInfo.getSubMchId(), test);
            if (!res.isSuccess()) {
                throw new Exception(res.getMsg());
            }
            // 营业场所内景照
            res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "5", merchantAccessBusinessDO.getStoreIndoorUrl(), merchantAccessInfo.getSubMchId(), test);
            if (!res.isSuccess()) {
                throw new Exception(res.getMsg());
            }

            if ("01".equals(acctType)) {
                res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "3", merchantAccessCard.getLicenseUrl(), merchantAccessInfo.getSubMchId(), test);
                if (!res.isSuccess()) {
                    throw new Exception(res.getMsg());
                }
            } else {
                // 对公上传“开户许可证/印鉴卡”，法人对私和非法人对私须上传“结算卡正面照”
                res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "3", merchantAccessCard.getSettleCardFrontUrl(), merchantAccessInfo.getSubMchId(), test);
                if (!res.isSuccess()) {
                    throw new Exception(res.getMsg());
                }
            }


            //（1个体工商户 2企业 3政府及事业单位 4小微 5其他机构组织）
            if (!"4".equals(mchtMode)) {
                // 营业执照
                res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "12", merchantAccessLicense.getLicenseUrl(), merchantAccessInfo.getSubMchId(), test);
                if (!res.isSuccess()) {
                    throw new Exception(res.getMsg());
                }
                ///** 账户类型：01 对公 02法人对私 03非法人对私 */
                if ("03".equals(acctType)) {
                    //非法人对私身份证正面照 非法人对私身份证反面照  15：非法人对私上传的授权书
                    res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "13", merchantAccessCard.getCertFrontUrl(), merchantAccessInfo.getSubMchId(), test);
                    if (!res.isSuccess()) {
                        throw new Exception(res.getMsg());
                    }
                    res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "14", merchantAccessCard.getCertBackUrl(), merchantAccessInfo.getSubMchId(), test);
                    if (!res.isSuccess()) {
                        throw new Exception(res.getMsg());
                    }
                    res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "15", merchantAccessCard.getAuthUrl(), merchantAccessInfo.getSubMchId(), test);
                    if (!res.isSuccess()) {
                        throw new Exception(res.getMsg());
                    }
                    if (CollectionUtils.isEmpty(merchantAccessBusinessDO.getFileUrls())) {
                        throw new Exception("请上传非法人授权结算书合影");
                    }
                    //非法人授权结算书合影
                    res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "17", merchantAccessBusinessDO.getFileUrls().get(0), merchantAccessInfo.getSubMchId(), test);
                    if (!res.isSuccess()) {
                        throw new Exception(res.getMsg());
                    }
                }
                // 收银台照
                res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "18", merchantAccessBusinessDO.getStoreCashierDeskUrl(), merchantAccessInfo.getSubMchId(), test);
                if (!res.isSuccess()) {
                    throw new Exception(res.getMsg());
                }
            } else {
                // 收银台照
                res = fileUpload(gtzfPayConfig, merchantAccessCert.getPhone(), timestamp, "19", merchantAccessBusinessDO.getStoreCashierDeskUrl(), merchantAccessInfo.getSubMchId(), test);
                if (!res.isSuccess()) {
                    throw new Exception(res.getMsg());
                }
            }
            return CommonResult.success(timestamp);
        } catch (Exception e) {
            log.error("上传图片异常", e);
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_FILE_ERROR.getCode(), e.getMessage());
        }
    }

    /**
     * 文件上传
     *
     * @param fileUrl
     * @param gtzfPayConfig
     * @return
     * @throws Exception
     */
    public static CommonResult<String> fileUpload(GtzfPayConfig gtzfPayConfig, String custLogin, String timestamp, String flag, String fileUrl, String custId, boolean test) {
        if (!file(fileUrl)) {
            log.info("文件格式错误 跳过文件上传:fileUrl:{},flag:{}", fileUrl, flag);
            return CommonResult.error(1,"编号["+flag+"]图片缺失" );
        }
        try {
            GtzfUploadRequest request = new GtzfUploadRequest();
            request.setCustLogin(custLogin);
            request.setAgetId(gtzfPayConfig.getAgetId());

            request.setOperType("1");
            if (StringUtils.hasText(custId)) {
                request.setOperType("2");
                request.setCustId(custId);
            }

            if (StringUtils.hasText(timestamp)) {
                request.setTimestamp(timestamp);
            }
            request.setVersion("1.0.0");

            request.setFlag(flag);
            String imgBase = image2Base64(fileUrl);
            //1：身份证正面照片  2：身份证反面照片  3：对公上传“开户许可证/印鉴卡”，法人对私和非法人对私须上传“结算卡正面照”  4：营业场所门头照  5：营业场所内景照  6：补充材料①  7：补充材料②
            // 8：补充资料③（手持结算卡照片） 9：事业单位证明函照片  10：补充材料⑤ 12：营业执照  13：非法人对私身份证正面照  14：非法人对私身份证反面照  15：非法人对私上传的授权书    16：结算人站门头照（储备字段无需处理）
            // 17：非法人授权结算书合影  18：收银台照   19：结算人收银台照  20：入网协议照① 21：入网协议照② 22：入网协议照③ 23：入网协议照④ 24：入网协议照⑤ 25：入网协议照⑥ 26：入网协议照⑦ 27：入网协议照⑧ 28：入网协议照⑨
            // 29：入网协议照⑩ 35：入网协议照⑪
            switch (flag) {
                case "1":
                    request.setCredPhotoFront(imgBase);
                    break;
                case "2":
                    request.setCredPhotoBack(imgBase);
                    break;
                case "3":
                    request.setAuthPic(imgBase);
                    break;
                case "4":
                    request.setDoorHeaderPhoto(imgBase);
                    break;
                case "5":
                    request.setIndoorScenesPhoto(imgBase);
                    break;
                case "6":
                    request.setFiled1(imgBase);
                    break;
                case "7":
                    request.setFiled2(imgBase);
                    break;
                case "8":
                    request.setFiled3(imgBase);
                    break;
                case "9":
                    request.setFiled4(imgBase);
                    break;
                case "10":
                    request.setFiled5(imgBase);
                    break;
                case "12":
                    request.setBusPhotoFront(imgBase);
                    break;
                case "13":
                    request.setCredPicF(imgBase);
                    break;
                case "14":
                    request.setCredPicB(imgBase);
                    break;
                case "15":
                    request.setAuthCert(imgBase);
                    break;
                case "17":
                    request.setStlAuth(imgBase);
                    break;
                case "18":
                    request.setCashierPhoto(imgBase);
                    break;
                case "19":
                    request.setJsrcPhoto(imgBase);
                    break;
                case "20":
                    request.setInfoPhoto1(imgBase);
                    break;
                case "21":
                    request.setInfoPhoto2(imgBase);
                    break;
                case "22":
                    request.setInfoPhoto3(imgBase);
                    break;
                case "23":
                    request.setNetPhoto1(imgBase);
                    break;
                case "24":
                    request.setNetPhoto2(imgBase);
                    break;
                case "25":
                    request.setNetPhoto3(imgBase);
                    break;
                case "26":
                    request.setNetPhoto4(imgBase);
                    break;
                case "27":
                    request.setNetPhoto5(imgBase);
                    break;
                case "28":
                    request.setNetPhoto6(imgBase);
                    break;
                case "29":
                    request.setNetPhoto7(imgBase);
                    break;
                case "33":
                    request.setBeneficiarCredFront(imgBase);
                    break;
                case "34":
                    request.setBeneficiarCredBack(imgBase);
                    break;
                case "37":
                    request.setHandAuthPic(imgBase);
                    break;
            }

            String sign = GtzfPayRsaUtil.encrypt(JSONUtil.parseObj(request), gtzfPayConfig.getMchPublicKey());
            request.setSign(sign);

            log.info("国通支付上传图片请求参数:{}", request);
            String url = domain(test) + GtzfPayConstant.MERCHANT_PIC_UPLOAD;
            String response = HttpUtils.post(url, JSONUtil.toJsonStr(request));
            log.info("国通支付上传图片返回参数:{}", response);

            GtzfResponse<UploadBody> rspBody = JsonUtils.parseObject(response, new TypeReference<GtzfResponse<UploadBody>>() {
            });
            if (!"000000".equals(rspBody.getCode())) {
                return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_FILE_ERROR.getCode(), StringUtils.hasText(rspBody.getMsg()) ? rspBody.getMsg() : "图片上传异常");
            }
            return CommonResult.success(rspBody.getData().getTimestamp());
        } catch (Exception e) {
//            e.printStackTrace();
            log.error("上传图片异常:{}", e.getMessage());
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_FILE_ERROR.getCode(), e.getMessage());
        }
    }

    public static boolean file(String fileUrl) {
        if (!StringUtils.hasText(fileUrl)) {
            return false;
        }
        int indexOf = fileUrl.lastIndexOf(StringPool.SLASH);
        if (indexOf < 0) {
            return false;
        }
        String fileType = fileUrl.substring(indexOf);
        if (!fileType.contains(StringPool.DOT)) {
            return false;
        }
        return true;
    }

    private static String image2Base64(String imageUrl) throws IOException {
        URL url = new URL(imageUrl);
        InputStream inputStream = url.openStream();
        // 将图片转换为 Base64 编码的字符串
        byte[] imageBytes = IoUtil.readBytes(inputStream);
        String base64String = Base64.encode(imageBytes);
        // 输出 Base64 字符串
        IoUtil.close(inputStream);
        return base64String;
    }

}
